<template>

  <el-button type="primary" @click="add()" v-has-permission="'product:add'">录入产品</el-button>

  <!-- 产品列表 -->
  <!--
    :data  单向绑定表格数据

    @selection-change="handleSelectionChange"   选择改变事件
      勾选或者取消勾选复选框时触发该函数
      注意：这个函数使用的时候不需要加括号，函数触发时会自动传入参数，参数是勾选了复选框的选项数组
  -->
  <el-table
      :data="productList"
      style="width: 100%">

    <!-- type="index"  序号以1递增 -->
    <el-table-column type="index" label="序号" width="60px" />
    <el-table-column property="name" label="产品名称" />
    <el-table-column property="guidePriceS" label="官方指导起始价" />
    <el-table-column property="guidePriceE" label="官方指导最高价" />
    <el-table-column property="quotation" label="经销商报价" />
    <el-table-column label="状态" width="80" >
      <template #default="scope">
        {{ scope.row.state === 0 ? '在售' : '下架' }}
      </template>
    </el-table-column>
    <el-table-column property="createByDO.name" label="创建者" />
    <el-table-column property="createTime" label="创建时间" width="180" />
    <el-table-column property="editByDO.name" label="编辑者" />
    <el-table-column property="editTime" label="编辑时间" width="180" />
    <el-table-column label="操作" >
      <!-- 作用域插槽 -->
      <template #default="scope">
        <!-- scope.row  获取当前行的数据对象 -->
        <el-button type="success" @click="edit(scope.row)" v-hasPermission="'product:edit'">编辑</el-button>
      </template>
    </el-table-column>
  </el-table>

  <!--
    分页功能
      layout="prev, pager, next"  组件布局，子组件名用逗号分隔  prev, pager, next, jumper, ->, total
      @prev-click="toPage" 点击上一页触发函数
      @next-click="toPage" 点击下一页触发函数
      @current-change="toPage"  当前页发生改变时触发函数
      注意：这里的函数不要加括号，element-plus会自动传递一个参数（当前页数）
  -->
  <el-pagination
      background
      layout="prev, pager, next"
      :page-size="this.pageSize"
      :total="this.total"
      @prev-click="toPage"
      @next-click="toPage"
      @current-change="toPage"/>

  <!-- 产品信息弹窗（产品的录入和编辑共用此弹窗） -->
  <el-dialog
      v-model="productDialogVisible"
      :title="this.productQuery.id > 0 ? '编辑产品' : '录入产品'"
      width="55%"  center  draggable
      :close-on-click-modal="false"
      :destroy-on-close="true">

    <!-- :model       表单绑定的数据 -->
    <!-- label-width  表单整体距离左侧的宽度 -->
    <!-- :rules       绑定验证规则 -->
    <!-- ref          表单提交之前验证表单的验证规则 -->
    <el-form :model="productQuery" label-width="130px" :rules="productRules" ref="productRefForm">

      <!-- 产品名称 -->
      <el-form-item label="产品名称" prop="name">
        <el-input v-model.trim="productQuery.name" />
      </el-form-item>

      <!-- 官方指导起始价 -->
      <el-form-item label="官方指导起始价" prop="guidePriceS">
        <el-input type="number" v-model.trim="productQuery.guidePriceS" />
      </el-form-item>

      <!-- 官方指导最高价 -->
      <el-form-item label="官方指导最高价" prop="guidePriceE">
        <el-input type="number" v-model.trim="productQuery.guidePriceE" />
      </el-form-item>

      <!-- 经销商报价 -->
      <el-form-item label="经销商报价" prop="quotation">
        <el-input type="number" v-model.trim="productQuery.quotation" />
      </el-form-item>

      <!-- 产品状态（录入的时候不需要渲染，录入的新产品都是在售状态） -->
      <el-form-item label="产品状态" prop="state" v-if="this.productQuery.id">
        <el-select v-model="productQuery.state">
          <el-option label="在售" :value="0" />
          <el-option label="下架" :value="1" />
        </el-select>
      </el-form-item>

      <el-form-item>
        <!-- 根据用户不同的操作调用不同的执行方法 -->
        <!-- 产品的id值大于0，则表明是编辑，否则就是录入，因为编辑的时候查询了产品信息，所以id值一定大于0 -->
        <el-button type="primary" @click="this.productQuery.id > 0 ? editProduct() : addProduct()">提交</el-button>
        <el-button @click="this.productDialogVisible = false">关闭</el-button>
      </el-form-item>

    </el-form>

  </el-dialog>

</template>

<script>
  import {doGet, doPost, doPut} from "../http/httpRequest.js";
  import {messageTip} from "../util/util.js";

  export default {
    name: "ProductView",

    // 注入父组件的函数
    inject: ['reload'],

    data() {
      return {
        // 产品列表
        productList: [
          {
            createByDO: {}, // 创建者对象
            editByDO: {}    // 编辑者对象
          }
        ],

        // 分页参数
        pageSize: 0,
        total: 0,

        // 产品对象对话框是否可见
        productDialogVisible: false,

        // 产品对象
        productQuery: { },

        // 产品表单的验证规则
        productRules: {
          name: [
            { required: true, message: '请输入产品名称', trigger: 'blur' }
          ],
          guidePriceS: [
            { required: true, message: '请输入官方指导起始价', trigger: 'blur' },
            { pattern: /^[0-9]+(\.[0-9]{2})?$/, message: '价格必须是整数或者两位小数', trigger: 'blur' }
          ],
          guidePriceE: [
            { required: true, message: '请输入官方指导最高价', trigger: 'blur' },
            { pattern: /^[0-9]+(\.[0-9]{2})?$/, message: '价格必须是整数或者两位小数', trigger: 'blur' },
            { validator: this.checkGuidePriceE, trigger: 'blur' }
          ],
          quotation: [
            { required: true, message: '请输入经销商报价', trigger: 'blur' },
            { pattern: /^[0-9]+(\.[0-9]{2})?$/, message: '价格必须是整数或者两位小数', trigger: 'blur' },
            { validator: this.checkQuotation, trigger: 'blur' }
          ]
        }
      }
    },

    // 钩子函数，页面渲染完成后自动执行
    mounted() {
      // 加载产品列表（第一页）
      this.loadTranList(1);
    },

    methods: {
      // 加载产品列表
      loadTranList(current) {
        // 向后端发送请求
        doGet("/api/product/list/all", {
          // 要查询第几页数据
          current: current
        }).then( (resp) => {
          if (resp.data.code === 200) {
            // 产品列表
            this.productList = resp.data.data.list;
            // 分页参数
            this.pageSize = resp.data.data.pageSize;
            this.total = resp.data.data.total;
          } else {
            messageTip("产品列表加载失败", "error");
          }
        })
      },

      // 分页函数
      toPage(current) {
        this.loadTranList(current);
      },

      // 录入产品按钮
      add() {
        // 清空产品对象信息
        this.productQuery = { };

        // 弹出对话框
        this.productDialogVisible = true;
      },

      // 编辑按钮
      edit(product) {
        // 将传入的产品对象信息显示到对话框中
        this.productQuery.id = product.id;
        this.productQuery.name = product.name;
        this.productQuery.guidePriceS = product.guidePriceS;
        this.productQuery.guidePriceE = product.guidePriceE;
        this.productQuery.quotation = product.quotation;
        this.productQuery.state = product.state;

        // 弹出对话框
        this.productDialogVisible = true;
      },

      // 验证 官方指导最高价不能低于官方指导起始价
      checkGuidePriceE(rule, value, callback) {
        // 注意：数字比较大小，使用Number()，否则会比较字符串大小
        if (Number(value) < this.productQuery.guidePriceS) {
          return callback(new Error('最高价不能低于起始价'));
        } else {
          return callback();
        }
      },

      // 验证 经销商指导价要介于官方指导起始价和官方指导最高价之间
      checkQuotation(rule, value, callback) {
        // 注意：数字比较大小，使用Number()，否则会比较字符串大小
        if (Number(value) > this.productQuery.guidePriceS && Number(value) < this.productQuery.guidePriceE) {
          return callback();
        } else {
          return callback(new Error('指导价要介于起始价和最高价之间'));
        }
      },

      // 提交按钮（录入）
      addProduct() {
        // 验证表单规则
        this.$refs.productRefForm.validate( (isValid) => {
          if (isValid) {
            // 使用FormData对象传参
            let formData = new FormData();
            // 将product对象的属性添加到FormData对象中
            for (let field in this.productQuery) {
              formData.append(field, this.productQuery[field]);
            }
            // 向后端发送请求
            doPost("/api/product/add", formData).then( (resp) => {
              if (resp.data.code === 200) {
                messageTip("录入成功", "success");
                // 返回刷新页面
                this.reload();
              } else {
                messageTip("录入失败", "error");
              }
            })
          }
        })
      },

      // 提交按钮（编辑）
      editProduct() {
        // 验证表单规则
        this.$refs.productRefForm.validate( (isValid) => {
          if (isValid) {
            // 使用FormData对象传参
            let formData = new FormData();
            // 将product对象的属性添加到FormData对象中
            for (let field in this.productQuery) {
              formData.append(field, this.productQuery[field]);
            }
            // 向后端发送请求
            doPut("/api/product/edit", formData).then( (resp) => {
              if (resp.data.code === 200) {
                messageTip("编辑成功", "success");
                // 返回刷新页面
                this.reload();
              } else {
                messageTip("编辑失败", "error");
              }
            })
          }
        })
      }
    }
  }
</script>

<style scoped>

  /* 表格 */
  .el-table {
    margin-top: 20px;  /* 上侧外边距 */
  }

  /* 分页栏 */
  .el-pagination {
    margin-top: 20px;  /* 上侧外边距 */
  }

</style>

